#include "global.h"


//--------------------------------------------------------------------------------------------------------------------------
//      V  A  R  I  A  B  L  E  S  
//--------------------------------------------------------------------------------------------------------------------------


bit Packet_ready;
bit TxRx_Error;
bit tout_enable;
bit rx_buf_full;
bit tx_busy;
bit handshaiking;
bit flag_error_norx;
//bit PacketReceived;





bank1  unsigned char rx_buf[RX_BUF_LENGHT];
unsigned char rx_buf_index=0;
unsigned char rx_buf_start=10;
unsigned char rx_packet_lenght=31;
unsigned char rx_byte_tout;
unsigned char txrxpause;

static bank3 signed char itu_packet_counter=1;


static bank3  unsigned int secs;  
static bank3  unsigned int seccount =0;
static bank3  unsigned int gsecs;  
static bank3  unsigned int gseccount =0;
bank3 struct sTime myTime;

bank2 unsigned char tx_buf[TX_BUF_LENGHT];
unsigned char tx_count=0;
unsigned char tx_buf_index=0;

bank1 unsigned char SystemTickCount=20; 
bank1 unsigned char PulseTickCount=5; 
bank1 unsigned int	RXWatchdog=2000; // 10sek/5ms = 10000/5=2000; 
unsigned char CommunicationState;



//--------------------------------------------------------------------------------------------------------------------------
//      F  U  N  C  T  I  O  N  S
//--------------------------------------------------------------------------------------------------------------------------





//--------------------------------------------------------------------------------------------------------------------------
unsigned char Get_Buf_Byte (unsigned char buff_start, unsigned char buff_position)
{	unsigned char temp;
	if ((buff_start + buff_position) < RX_BUF_LENGHT) 
	{	
		temp=buff_start+buff_position;
	}
	else
	{ 
		temp = (buff_start + buff_position ) -RX_BUF_LENGHT;
	};
	return rx_buf[temp];
};


static bank3 unsigned char stop_me=0;

void resetTime()
{
	seccount =0;
	secs=0;
};

unsigned int getSec(void)
{  
	return secs;
};


void resetgTime()
{
	gseccount =0;
	gsecs=0;
};

unsigned int getgSec(void)
{  
	return gsecs;
};


void interrupt												// Here be interrupt function - the name is
isr(void)															// unimportant.
{ 	unsigned char temp_i,temp_i1;
	static bank1 unsigned char checksum_reg;
	static unsigned char temp_dc, sum_dc;
//--------------------------------------------------------
	if (TMR1IF && TMR1IF)
	{ 	TMR1IF=0;
		TMR1Preload (65535-Tick+CAL_FACTOR);
		if (!SystemTickCount--)
		{	SystemTickCount=100;
			flag_system_tick=1;
			// ------- here we mast care a receiver ----------------
			if (FERR || OERR )
			{ 	CREN=0;
				TxRx_Error=1;
				temp_i=RCREG;
				OERR=0;
				FERR=0;				
				CREN=1;
			};
		};
// ================== Time Indication Section ========================
		if(	flag_sequence_running) // seems need only in sequence running situation
		{		if (seccount++ >400)
				{	secs+=1;
					seccount=0;
				};

				if (gseccount++ >400)
				{	gsecs+=1;
					if((myTime.seconds +=1) >59)
					{	myTime.seconds=0;
						if ((myTime.minutes+=1)>59)
						{	myTime.minutes=0;
							if ((myTime.hours+=1)>24) myTime.hours=0;
						}
					}
					gseccount=0;
				};
		};  
// ================== Time Indication Section ========================

		if (!PulseTickCount--)
		{	PulseTickCount=8;  //  40 ms 
			flag_pulse_tick=1;
		};

		if (flag_com_pause)
		{
			if (!txrxpause--) flag_com_pause=0;
		};

//================== communication statemashine ========================================================

			
				 // here we waiting for packet and if it good we start the job
		switch (CommunicationState)
		{
			case 0:
						if (flag_packet_received)
						{	flag_packet_received=0;
							CREN=0;

							if ((Odu==sourse)&&(Idu==destination))	// single part
							{
								  	CommunicationState =6; // IDU
									itu_packet_counter=2;
		
							} // main here is fast return to listening line
					 		else if ((Odu==sourse)&&(kCOM==destination))
							{	CommunicationState =1;
							} // main here is a time betseen receive and send
							else if ((Idu==sourse)&&(Odu==destination))	// full system
							{	CommunicationState =0;
							}
							else if ((Odu==sourse)&&(MSMP==destination))	// full system
							{	CommunicationState =0;
								asm("nop");
							}
							else 
							{
								CREN=1;
								CommunicationState =0;
							};
						};
					break;

			case 1:	// odu answered to ITU
			
							if ( itu_packet_counter-- <= 0)
							{
								CommunicationState = 0; 	// goto wait for packet
								CREN=1;					// we return to receiving state so need to enable receiver 
							}
							else
							{
								CommunicationState = 2; 									
							}		
					break;
			case 2:
			
						flag_com_pause=1;
						txrxpause=24; // 24*2.5ms = 60ms pause between RX and TX
						CommunicationState =3; 	
						asm("nop");	
					break;

			case 3:
						if((!flag_com_pause)&&(!TXIE))
						{	sum_dc=0;
							if (ITUMsgId++ >31) ITUMsgId=0; 

							for (temp_dc=0; temp_dc<4; temp_dc++)
							{	tx_buf[temp_dc]=ITUHeader[temp_dc];
							};
							tx_buf[4]=ITUMsgId;

							//---------- next block must be changed due to work with real  ITU---------
							for (temp_dc=0; temp_dc<6;temp_dc++)
							{	tx_buf[temp_dc+5]=MyITU.access[temp_dc];
							};

							for (temp_dc=0; temp_dc<11;temp_dc++)
							{	sum_dc+=tx_buf[temp_dc];
							};

							tx_buf[11]=(unsigned char)(0-sum_dc);					

							tx_buf_index=0;
							tx_count=12;
							TXIE=1;
							CommunicationState =4;  
						}	
					break;
			case 4:
						if(!TXIE)
						{	
						flag_com_pause=1;
						txrxpause=4; // 4*2.5ms = 10ms pause between RX and TX
						CommunicationState =5; 	
						asm("nop");	
						}
					break;

			case 5:
						if (!flag_com_pause)
						{	// Lets wait up to delay end and start receiver here
							CREN=1;
							CommunicationState =0; 		
						};
					break; 

				// ----- itu packet sent, waiting for ODU response 



			case 6:	 // prepare pause for IDU dummy packet
						flag_com_pause=1;
						txrxpause=24; // 24*2.5ms = 60ms pause between RX and TX
						CommunicationState =7; 	
						asm("nop");
					break;
			case 7: //  preparing IDU-> ODU packet
						if((!flag_com_pause)&&(!TXIE))
						{	
						
							if (IDUMsgId++ >31) IDUMsgId=0; 

							for (temp_dc=0; temp_dc<4; temp_dc++)
							{	tx_buf[temp_dc]=IDUHeader[temp_dc];
							};
							tx_buf[4]=IDUMsgId;

							//---------- next block must be changed due to work with real  IDU---------
							for (temp_dc=0; temp_dc<20;temp_dc++)
							{	tx_buf[temp_dc+5]=MyIDU.access[temp_dc];
							};

							sum_dc=0;
							for (temp_dc=0; temp_dc<25;temp_dc++)
							{	sum_dc+=tx_buf[temp_dc];
							};
							tx_buf[25]=(unsigned char)(0-sum_dc);					

							tx_buf_index=0;
							tx_count=26;
							TXIE=1;
							CommunicationState =8;    
						}	
					break;
			case 8:// sending  IDU->ODU
						if(!TXIE)
						{	
							flag_com_pause=1;
							txrxpause=12; // 24*2.5ms = 60ms pause between RX and TX
							if (flag_itu_start)
							{ 	
								CommunicationState =3;  // send itu packet	
								asm("nop");
							}
							else
							{
								CommunicationState =9; 	// continue odu-idu emulation
								asm("nop");				
							};	
						}
					break;

			case 9:
					if (!flag_com_pause)
						{	// Lets wait up to delay end and start receiver here
							CREN=1;
							CommunicationState =0; 
						};
					break;
			default:
						CREN=1;
						TXIE=0;
						RCIE=1;
						CommunicationState =0; 	
					break;
		}; // end of switch	

//==========================================================================================================================
	}; // end of T1 interrupt

	while (TXIF && TXIE)
	{
		if(tx_count) 
		{	tx_count--;
			TXREG = tx_buf[tx_buf_index++];
		} else 
		{	TXIE=0;
		}; // 		
	}; // end of  TXIF
//------------------------------------------------------------------------------------------
	while(RCIF && RCIE)// (RCIF) to prevent FIFO overflow
		{	
			temp_i1=RCREG;
			// prepare to add a new byte to the circular buffer
//			Put_Buf_Byte(temp_i1);
		if ((rx_buf_index+1)< RX_BUF_LENGHT ) // check if buffer not full 
			{	rx_buf_index+=1;						// increment byte index
			}
			else					// if buffer full
			{	rx_buf_full =1;	// report it
				rx_buf_start+=1;	// move  start point forward (first recorded byte will be lost)
				if (rx_buf_start >= RX_BUF_LENGHT) rx_buf_start=0;
			};  	//end of  place check and preparation 
	
				// here we  store recorded byte
		if ((rx_buf_index+rx_buf_start) < RX_BUF_LENGHT)
			{ 	rx_buf[rx_buf_start+rx_buf_index]=temp_i1;	
			}
			else
			{ 	
				rx_buf[(rx_buf_start + rx_buf_index)-RX_BUF_LENGHT]=temp_i1;	
			};
			// here we performing  packet job
			//  if start marker received -  move buffer start to marker position, reset index and prepare check sum


			checksum_reg+=temp_i1; 		//  calculating chaecksum	
		
			//====================== New Sync Byte received ==============================
			if (0xFE==temp_i1)
			{  	if ((rx_buf_start+rx_buf_index)>RX_BUF_LENGHT)
				{	rx_buf_start=(rx_buf_start+rx_buf_index)-RX_BUF_LENGHT;
				}
				else
				{	rx_buf_start=rx_buf_start+rx_buf_index;
				};
				rx_buf_index=0;
				checksum_reg=0xFE;
			};	// end of sync seeking
			
			//============================================================================

			if (3 == rx_buf_index )
			{
				 rx_packet_lenght = temp_i1 & 0b00011111; //  max =31 byte
			};

			if ( (rx_packet_lenght -1) == rx_buf_index )
				{	
					asm("nop");	
					if ( 0 == checksum_reg )
					{	
					// heer we check soursr and destination of received packet
						sourse = (Get_Buf_Byte (rx_buf_start,2)&0b00000111) ; // sourse
						destination = (Get_Buf_Byte (rx_buf_start,1)&0b00000111) ; // destination
					// here we copying the data packets 
					
						if (( sourse == Odu)&&( destination == Idu ))  //	Odu->Idu
						{	for (temp_i=0; temp_i<5;temp_i++)
							{	MyODUIDUHeader.access[temp_i]=Get_Buf_Byte (rx_buf_start,temp_i);
							};
							for (temp_i=0; temp_i<rx_packet_lenght-2;temp_i++)
							{	MyODU.access[temp_i]=Get_Buf_Byte (rx_buf_start,temp_i+5);
							};

stop_me =0;

						};

						if (( sourse == Idu)&&( destination == Odu ))  //	Odu->Idu
						{	for (temp_i=0; temp_i<5;temp_i++)
							{	MyIDUHeader.access[temp_i]=Get_Buf_Byte (rx_buf_start,temp_i);
							};
							for (temp_i=0; temp_i<rx_packet_lenght-2;temp_i++)
							{	MyIDU.access[temp_i]=Get_Buf_Byte (rx_buf_start,temp_i+5);
							};
						};

					
						if (( sourse == Odu)&&( destination == kCOM ))  //	Odu->kCOM
						{	for (temp_i=0; temp_i<5;temp_i++)
							{
								MyODUkCOMHeader.access[temp_i]=Get_Buf_Byte (rx_buf_start,temp_i);
							};
							for (temp_i=0; temp_i<rx_packet_lenght-2;temp_i++)
							{
								MyITU_answer.access[temp_i]=Get_Buf_Byte (rx_buf_start,temp_i+5);
							};
							asm("nop");

//==================================================
							if (2 == stop_me++)
								{					
									asm("nop");	
								};
//====================================================

						};

						if (( sourse == kCOM)&&( destination == Odu ))  // kCOM->ODU  this is our packet - do nothing
						{
						
						};

						flag_packet_good=1;
						flag_packet_received=1;
					};
				};
	};	

//--------------------------------------------------------
	if (T0IF && T0IE)
	{	T0IF=0; 			// reset interrupt flag
	}; // end of T0 interrupt

//------------------------- transmitting section ----------


}; // end of interrupt


